package com.ysm.smfu.view;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.ysm.smfu.R;

/**
 * Created by Administrator on 2016/11/1.
 */
public class RefreshLayout extends SwipeRefreshLayout {

    /**
     * listview实例
     */
    private ListView mListView;

    /**
     * 上拉监听器, 到了最底部的上拉加载操作
     */
    private OnLoadListener mOnLoadListener;

    /**
     * ListView的加载中footer
     */
    private View mListViewFooter;

    /**
     * 按下时的y坐标
     */
    private int mYDown;
    /**
     * 抬起时的y坐标, 与mYDown一起用于滑动到底部时判断是上拉还是下拉
     */
    private int mMoveY;
    private ProgressBar loading_pb;
    private TextView loading_txt;
    //    能够上拉加载时，当前页最小条目数
    private int loadCount = 10;

    //    没有加载
    private static final int NOLOAD = 2;
    //    准备加载
    private static final int ISPRELOAD = 3;
    //    正在加载中
    private static final int ISLOADING = 3;
    //    当前加载状态
    private int currentState = 2;
    private int padding;
    private int measuredHeight;
    private int lastVisiblePosition;
    private int i;
    private float downX;
    private float downY;
    private int totalHeight;
    private ListView listView;
    private int headHeight;
    private boolean isDrag;


    /**
     * @param context
     */
    public RefreshLayout(Context context) {
        this(context, null);
    }

    @SuppressLint("InflateParams")
    public RefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        addFootView(context);
    }

    private void addFootView(Context context) {
        mListViewFooter = LayoutInflater.from(context).inflate(
                R.layout.onloading, null, false);
        mListViewFooter.measure(0, 0);
        measuredHeight = mListViewFooter.getMeasuredHeight();
        loading_pb = (ProgressBar) mListViewFooter.findViewById(R.id.loading_pb);
        loading_txt = (TextView) mListViewFooter.findViewById(R.id.loading_txt);
        resetState();
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        // 初始化ListView对象
        if (mListView == null) {
            getListView();
            mListView.addFooterView(mListViewFooter);
        }
    }

    /**
     * 获取ListView对象
     */
    private void getListView() {
        int childs = getChildCount();
        if (childs > 1) {
            View childView = getChildAt(1);
            if (childView instanceof ListView) {
                mListView = (ListView) childView;
            }
        }
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        final int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_MOVE:
                lastVisiblePosition = mListView.getLastVisiblePosition();
                i = mListView.getAdapter().getCount() - mListView.getFooterViewsCount() - 1;
//              如果添加的脚布局可见，则通过改变脚布局的padding值，实现上拉效果
                if (lastVisiblePosition >= i) {
                    // 获取滑动到最底部时的按下坐标
                    if (mYDown == 0)
                        mYDown = (int) event.getY();
                    // 移动时坐标
                    mMoveY = (int) event.getY();
                    int disY = mMoveY - mYDown;
                    if (disY < 0) {
                        padding = padding - disY;
                        mListViewFooter.setPadding(0, 0, 0, padding);
                        if (!canLoad()) {   //判断是否满足需要加载条件
                            mListViewFooter.setVisibility(GONE);    //不满足加载更多的条件，则隐藏脚布局，只进行上拉操作
                        } else if (currentState == NOLOAD)  // 能加载则进行状态切换
                            currentState = ISPRELOAD; //改变加载状态为准备加载
                        else if (currentState == ISLOADING)
                            isMove = true;// 设置正在加载时,向上拖动的标记
                    }
                }
                break;

            case MotionEvent.ACTION_UP:
                // 松手时，恢复状态
                isMove = false;
                mYDown = 0;
                // 抬起
                if (lastVisiblePosition > i) {
//                    当上拉时脚布局完全显示，则松手时开始执行加载操作
                    releaseAndLoad();
                } else {
//                    重置状态
                    resetState();
                }
                break;
        }
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
//        在viewPager中嵌套MyRefreshLayout，RefreshLayout中嵌套ListView,ListView中的子条目需要左右滑动时，
//        子View无法从viewPager抢夺焦点，暂时通过计算listView中子条目的高度方法打一补丁，找到解决方案再来替代 TODO
        if (isDrag) {   //如果子条目可以拖动,则计算listView中子条目的总高度
            if (totalHeight == 0) {
                for (int i = 0; i < getChildCount(); i++) {
                    View childAt = getChildAt(i);
                    if (childAt instanceof ListView)
                        listView = (ListView) childAt;
                }
                if (listView.getAdapter() != null && listView.getChildAt(0) != null)
                    for (int i = 0; i < listView.getChildCount(); i++) {
                        View listItem = listView.getChildAt(i);
                        if (listItem != null) {
                            listItem.measure(0, 0);
                            // 统计所有子项的总高度
                            totalHeight += listItem.getMeasuredHeight();
                            if (i < listView.getHeaderViewsCount())
                                headHeight += totalHeight;
                        }
                    }
            }
            float y = ev.getY();
            if (y > totalHeight || y < headHeight) { //如果触摸范围不在listView的子条目范围内则允许父控件打断事件
                getParent().requestDisallowInterceptTouchEvent(false);
            } else   //如果触摸范围在listView的子条目范围内则将事件交给子条目处理
                getParent().requestDisallowInterceptTouchEvent(true);
        }
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = ev.getX();
                downY = ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                float moveX = ev.getX();
                float moveY = ev.getY();
                float disX = moveX - downX;
                float dixY = moveY - downY;
                if (Math.abs(disX) > Math.abs(dixY)) { //如果是左右滑动，则将事件向下传递
                    return false;
                }
                downX = moveX;
                downY = moveY;
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }

    /**
     * 释放并加载
     */
    private void releaseAndLoad() {
        mListViewFooter.setPadding(0, 0, 0, 0); // 将脚布局位置置于底部
        if (currentState == ISPRELOAD) { // 如果状态为准备加载，则开始加载
            //  是否需要上拉加载
            mOnLoadListener.onLoad();
            currentState = ISLOADING; //改变加载状态
        } else
            resetState();
    }

    /**
     * 加载完成
     *
     * @param isHasData 是否加载到数据
     */
    public void setLoading(boolean isHasData) {
        if (isHasData) {  //如果加载到数据，则重置状态
            resetState();
        } else { //没有加载到数据，则显示没有更多数据，并做动画隐藏脚布局
            loading_txt.setText("没有更多数据");
            loading_pb.setVisibility(GONE);
            doAnimator();
        }
    }

    /**
     * 是否正在滑动
     */
    boolean isMove;

    /**
     * 缓慢隐藏脚布局
     */
    private void doAnimator() {
        if (isMove)
            return;
        ValueAnimator animator = ValueAnimator.ofInt(0, -measuredHeight);
        animator.setDuration(500);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int value = (int) animation.getAnimatedValue();
//                可以通过改变top或者bottom的值，来实现隐藏脚布局时的动画效果：覆盖隐藏获取下移消失
                mListViewFooter.setPadding(0, value, 0, 0);
            }
        });
        animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                resetState();
            }

            @Override
            public void onAnimationCancel(Animator animation) {
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
            }
        });
        animator.start();
    }

    /**
     * 重置显示状态
     */
    private void resetState() {
        mListViewFooter.setVisibility(VISIBLE);
        loading_pb.setVisibility(VISIBLE);
        loading_txt.setText("努力加载中..");
        currentState = NOLOAD;
        padding = -measuredHeight;
        mListViewFooter.setPadding(0, 0, 0, padding);
    }

    /**
     * 根据现有条目数决定是否需要加载更多
     *
     * @return
     */
    private boolean canLoad() {
        if (mListView != null && mOnLoadListener != null) {
            int count = mListView.getAdapter().getCount();
            if (count - mListView.getHeaderViewsCount() - mListView.getFooterViewsCount() >= loadCount) {
                return true;
            }
        }
        return false;
    }

    /**
     * 子条目是否可以左右拖动
     *
     * @param isDrag
     */
    public void setIsDrag(boolean isDrag) {
        this.isDrag = isDrag;
    }

    /**
     * 加载更多接口
     */
    public interface OnLoadListener {
        void onLoad();
    }

    /**
     * 加载更多回调
     *
     * @param onLoadListener
     */
    public void setOnLoadListener(OnLoadListener onLoadListener) {
        mOnLoadListener = onLoadListener;
    }
}
